package database.model;


import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.Table;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Restrictions;
import org.htmlparser.Node;
import org.htmlparser.Parser;
import org.htmlparser.filters.AndFilter;
import org.htmlparser.filters.HasAttributeFilter;
import org.htmlparser.filters.HasChildFilter;
import org.htmlparser.filters.TagNameFilter;
import org.htmlparser.util.NodeIterator;
import org.htmlparser.util.NodeList;
import org.htmlparser.util.ParserException;

import utilities.ConvertService;
import database.HibernateUtil;

@Entity
@Table(name = "ARTICLE")
public class Article implements Serializable{
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 598171758106162444L;
	private Long _id;
	private String _url;
	private String _title;
	private String _subtitle;
	private String _publicationDate;
	private String _content;
	private List<Section> _sections;
	private Date _lastBuildDate;
	
	
	public static Article update(String url,InputStream htmlFlux) 
	{
		Session session = HibernateUtil.currentSession();
		Transaction trans = session.beginTransaction();
		Article article = Article.getArticleWithUrl(session,url);
		boolean isUpdate = article != null;
		if(!isUpdate)
		{
			article = new Article();
			System.out.println("save new by article");
		}
		article.setUrl(url);
		System.out.println("parsing article =====================");
		try {
			String htmlArticleString = ConvertService.stringFromStream(htmlFlux);
			Parser parser = new Parser(htmlArticleString);
			HasAttributeFilter filterTitle = new HasAttributeFilter("class", "Title");
			AndFilter filterBody = new AndFilter( new HasAttributeFilter("class", "tdbody"), new HasChildFilter(filterTitle));
			NodeList list = parser.parse(filterBody);
			Node bodyNode = list.elementAt(0);
			NodeList titleList = new NodeList();
			
			NodeList subtitleList = new NodeList();
			HasAttributeFilter filterSubtitle = new HasAttributeFilter("class","Lead");
			NodeList contentList = new NodeList();
			AndFilter filterImage = new AndFilter(new TagNameFilter("TABLE"), 
												  new HasChildFilter(new AndFilter(new TagNameFilter("TR"), 
														  						   new HasChildFilter(new AndFilter(new TagNameFilter("TD"), 
														  								   							new HasChildFilter(new TagNameFilter("IMG")))))));
			AndFilter filterContent =new AndFilter(new TagNameFilter("p"), new HasAttributeFilter("class","Normal"));
			for(NodeIterator it = list.elements(); it.hasMoreNodes();)
			{
				Node node = it.nextNode();
				node.collectInto(titleList, filterTitle);
				node.collectInto(subtitleList, filterSubtitle);
				node.collectInto(contentList, filterContent);
			}
			article.setTitle(titleList.elementAt(0).getFirstChild().getText());
			article.setSubtitle(subtitleList.elementAt(0).getFirstChild().getText());
			article.setContent(contentList.toHtml());
			System.out.println("ok "+article.getContent());
			System.out.println("Session size "+article.getSections().size());
			
			article.setLastBuildDate(new Date());
			article.save(session,isUpdate);
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ParserException e) {
			e.printStackTrace();
		}
		finally
		{
			trans.commit();
			HibernateUtil.closeSession();
		}

		return article;
	}
	public static Article getArticleWithUrl(Session session,String url)
	{
		@SuppressWarnings("unchecked")
		List<Article> list =session.createCriteria(Article.class).setFetchSize(1).add(Restrictions.like("url", url)).list();
		return list.size() == 0? null:list.get(0);
	}
	
	public void save(Session session,boolean isUpdate)
	{
		if(isUpdate)
			session.update(this);
		else
			session.save(this);
	}
	//--------------------------------------------------------------------------------------------------------------
	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	@Column(name = "ARTICLE_ID")
	public Long getId(){ return _id; }
	public void setId(Long id){ _id = id; }
	
	public String getUrl(){ return _url; }
	public void setUrl(String url){ _url = url;}
	
	@Column(columnDefinition="MEDIUMTEXT")
	public String getTitle(){ return _title; }
	public void setTitle(String title){ _title = title; }
	
	@Column(columnDefinition="MEDIUMTEXT")
	public String getSubtitle() { return _subtitle; }
	public void setSubtitle(String subtitle) { _subtitle = subtitle;}
	
	public String getPublicationDate() { return _publicationDate; }
	public void setPublicationDate(String publicationDate) { _publicationDate = publicationDate;}
	
	@Column(columnDefinition="LONGTEXT")
	public String getContent() { return _content; }
	public void setContent(String content) { _content = content;}
	
	@ManyToMany(
	        cascade = {CascadeType.PERSIST, CascadeType.MERGE},
	        mappedBy = "articles",
	        targetEntity = Section.class
	    )
	public List<Section> getSections(){ return _sections; }
	public void setSections(List<Section> sections) { _sections = sections; }
	
	public Date getLastBuildDate(){ return _lastBuildDate; }
	public void setLastBuildDate(Date lastBuildDate){ _lastBuildDate = lastBuildDate; }
}
